using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Net;
using System.Net.NetworkInformation;

namespace Pscx.Commands.Net
{
    public class PingHostStatistics
    {
        public readonly IPHostEntry Host;
        public readonly List<PingReply> Replies = new List<PingReply>();

        bool calculated;
        int sent = 0;
        int received = 0;

        long min = long.MaxValue;
        long max = long.MinValue;
        long avg = 0;

        public PingHostStatistics(IPHostEntry host)
        {
            this.Host = host;
        }

        internal void WriteToHost(PingHostCommand command)
        {
            command.InvokeCommand.InvokeScript(
                "$args[0] | Format-Custom | Out-Host", 
                false, 
                PipelineResultTypes.Output, 
                null, this);
        }


        void EnsureIsCalculated()
        {
            if (calculated) return;

            long avgAccumulator = 0;

            foreach (PingReply reply in Replies)
            {
                sent++;

                if (reply.Status == IPStatus.Success)
                {
                    min = Math.Min(min, reply.RoundtripTime);
                    max = Math.Max(max, reply.RoundtripTime);

                    avgAccumulator += reply.RoundtripTime;

                    received++;
                }
            }

            if (received > 0)
            {
                avg = (long)(avgAccumulator / received);
            }
            else
            {
                min = max = 0;
            }

            calculated = true;
        }

        #region Properties
        public int Sent
        {
            get
            {
                EnsureIsCalculated();
                return sent;
            }
        }
        public int Received
        {
            get
            {
                EnsureIsCalculated();
                return received;
            }
        }
        public int Lost
        {
            get
            {
                EnsureIsCalculated();
                return sent - received;
            }
        }
        public double Loss
        {
            get { return 100 * Lost / Sent; }
        }

        public long MinimumTime
        {
            get
            {
                EnsureIsCalculated();
                return min;
            }
        }
        public long MaximumTime
        {
            get
            {
                EnsureIsCalculated();
                return max;
            }
        }
        public long AverageTime
        {
            get
            {
                EnsureIsCalculated();
                return avg;
            }
        }
        #endregion
        
    }
}
